<template>
  <div class="app-container">
    <!-- 搜索表单 -->
    <el-form
      :model="queryParams"
      ref="queryForm"
      size="small"
      :inline="true"
      v-show="showSearch"
      label-width="auto"
    >
      <el-form-item label="设备编号" prop="deviceCode">
        <el-input
          v-model="queryParams.deviceCode"
          placeholder="请输入设备编号"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="设备名称" prop="deviceName">
        <el-input
          v-model="queryParams.deviceName"
          placeholder="请输入设备名称"
          clearable
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="所属部门" prop="deptId">
        <treeselect
          v-model="queryParams.deptId"
          :options="deptList"
          :normalizer="normalizer"
          placeholder="选择所属部门"
          style="width: 200px"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 设备状态卡片列表 -->
    <div class="device-card-container">
      <el-card
        v-for="(device, index) in list"
        :key="device.deviceId || index"
        class="device-card"
      >
        <div class="device-info" @click="openDeviceDetail(device)">
          <div class="device-header">
            <div class="device-no">{{ device.deviceName || '-' }}</div>
            <div class="device-status" :class="getStatusClass(device)">
              {{ getStatusLabel(device) || '--' }}
              <i class="el-icon-arrow-right"></i>
            </div>
          </div>
          <div class="device-content">
            <div class="dashboard-container">
              <div class="dashboard" :style="getDashboardStyle(device)">
                <div class="dashboard-inner">
                  <div class="dashboard-percentage">{{ device.startRate || '0.00' }}%</div>
                  <div class="dashboard-label">开动率</div>
                </div>
              </div>
            </div>
            <div class="status-list">
              <div class="status-item">
                <div class="status-label">运行</div>
                <div class="status-value">{{ device.runTime || '00:00:00' }}</div>
              </div>
              <div class="status-item">
                <div class="status-label">待机</div>
                <div class="status-value">{{ device.standbyTime || '00:00:00' }}</div>
              </div>
              <div class="status-item">
                <div class="status-label">告警</div>
                <div class="status-value">{{ device.warningTime || device.waringTime || '00:00:00' }}</div>
              </div>
              <div class="status-item">
                <div class="status-label">关机</div>
                <div class="status-value">{{ device.shutdownTime || '00:00:00' }}</div>
              </div>
            </div>
          </div>
        </div>
      </el-card>
    </div>

    <!-- 分页组件 -->
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="queryParams.pageNo"
      :limit.sync="queryParams.pageSize"
      @pagination="getList"
    />

    <!-- 设备详情弹框 -->
    <el-dialog
      :visible.sync="detailDialogVisible"
      width="80%"
      top="20px"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="true"
    >
      <!-- 设备状态分布长线图 -->
      <div class="chart-section">
        <h3 class="chart-title">设备状态分布</h3>
        <div class="chart-content">
          <DeviceStatusDistribution
            :chart-data="statusDistributionData"
            height="80px"
            width="100%"
          />
        </div>
      </div>

      <!-- 设备开动率折线图 -->
      <div class="chart-section">
        <h3 class="chart-title">设备开动率统计</h3>
        <div class="chart-content">
          <DeviceStartRateChart
            :chart-data="startRateData"
            height="350px"
            width="100%"
          />
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import * as DeviceApi from '@/api/system/device/index.js';
import { listDept } from '@/api/system/dept';
import Treeselect from '@riophae/vue-treeselect';
import Pagination from '@/components/Pagination';
import DeviceStatusDistribution from './components/DeviceStatusDistribution.vue';
import DeviceStartRateChart from './components/DeviceStartRateChart.vue';
import '@riophae/vue-treeselect/dist/vue-treeselect.css';

export default {
  name: 'DeviceStatus',
  components: {
    Treeselect,
    Pagination,
    DeviceStatusDistribution,
    DeviceStartRateChart
  },
  data() {
    return {
      // 加载状态
      loading: true,
      // 是否显示搜索
      showSearch: true,
      // 总条数
      total: 0,
      // 设备列表
      list: [],
      // 部门列表
      deptList: [],
      // 详情弹框显示状态
      detailDialogVisible: false,
      // 当前设备
      currentDevice: null,
      // 设备状态配置
      deviceStatusConfig: [
        { value: '1', label: '运行', class: 'running', color: '#1ebe66' },
        { value: '2', label: '待机', class: 'standby', color: '#ffb900' },
        { value: '3', label: '告警', class: 'alarm', color: '#fd163c' },
        { value: '0', label: '关机', class: 'close', color: '#777777' }
      ],
      // 状态分布数据
      statusDistributionData: [],
      // 仪表盘颜色
      colors: ['#1890ff'],
      // 查询参数
      queryParams: {
        pageNo: 1,
        pageSize: 20,
        deviceCode: null,
        deviceName: null,
        deptId: null,
        deptName: null
      },
      // 图表数据
      startRateData: {}
    };
  },

  // 生命周期钩子
  created() {
    // 先获取部门列表，再获取设备列表
    this.getOptions();
  },

  methods: {
    /**
     * 搜索按钮操作
     */
    handleQuery() {
      this.queryParams.pageNo = 1;
      this.getList();
    },

    /** 生成模拟图表数据 */
    generateMockChartData() {
      // 生成模拟设备状态分布数据
      this.generateMockDistributionData();
      // 生成模拟设备开动率数据
      this.generateMockStartRateData();
    },

    /** 生成模拟设备状态分布数据 */
    generateMockDistributionData() {
      const now = new Date();
      const data = [];

      // 生成过去24小时的状态变化记录
      for (let i = 23; i >= 0; i--) {
        const startTime = new Date(now.getTime() - i * 60 * 60 * 1000);
        const duration = 60 * 60 * 1000; // 1小时
        const endTime = new Date(startTime.getTime() + duration);

        // 随机状态，倾向于运行和待机
        const statusOptions = ['1', '1', '1', '2', '2', '3', '0'];
        const randomIndex = Math.floor(Math.random() * statusOptions.length);
        const state = statusOptions[randomIndex];

        data.push({
          startTime: startTime.toISOString(),
          endTime: endTime.toISOString(),
          duration: duration,
          state: state,
          yield: Math.floor(Math.random() * 1000) // 随机产量
        });
      }

      this.statusDistributionData = data;
    },

    /** 生成模拟设备开动率数据 */
    generateMockStartRateData() {
      const data = {};
      const now = new Date();

      // 生成过去24小时的开动率数据
      for (let i = 23; i >= 0; i--) {
        const time = new Date(now.getTime() - i * 60 * 60 * 1000);
        const hour = time.getHours().toString().padStart(2, '0');
        const key = `${hour}:00`;

        // 生成一个合理的随机值，模拟真实数据波动
        // 早上和晚上较低，工作时间较高
        let baseRate = 50;
        if (hour >= '08' && hour <= '20') {
          baseRate = 70 + Math.sin((parseInt(hour) - 8) / 12 * Math.PI) * 20;
        }
        const randomFactor = (Math.random() - 0.5) * 20;
        const rate = Math.max(0, Math.min(100, baseRate + randomFactor));

        data[key] = Number(rate.toFixed(2));
      }

      this.startRateData = data;
    },

    /**
     * 获取部门列表
     */
    async getOptions() {
      try {
        const response = await listDept();
        this.deptList = this.handleTree(response.data, 'id')[0]?.children || [];
        // 部门列表加载完成后获取设备列表
        this.getList();
      } catch (error) {
        console.error('获取部门列表失败:', error);
        // 即使部门列表获取失败，也尝试获取设备列表
        this.getList();
      }
    },

    /**
     * 查询设备列表
     */
    async getList() {
      try {
        this.loading = true;
        const res = await DeviceApi.getDevicePage(this.queryParams);
        this.list = res.data.list || [];
        this.total = res.data.total || 0;
      } catch (error) {
        console.error('获取设备列表失败:', error);
        // 加载模拟数据用于开发测试
        this.list = this.getMockData();
        this.total = this.list.length;
      } finally {
        this.loading = false;
      }
    },

    /**
     * 打开设备详情
     */
    openDeviceDetail(device) {
      if (!device) return;

      // 创建设备副本
      this.currentDevice = { ...device };
      // 显示详情弹框
      this.detailDialogVisible = true;

      // 强制Vue更新DOM后生成模拟数据
      this.$nextTick(() => {
        const mockData = this.generateMockDeviceData(device);
        this.statusDistributionData = mockData.statusDistribution;
        this.currentDevice.startRate = mockData.startRate;

        // 生成该设备的开动率数据
        this.generateMockStartRateData();
      });
    },

    /**
     * 生成设备相关模拟数据
     */
    generateMockDeviceData(device) {
      if (!device) {
        return {
          startRate: '0.00',
          statusDistribution: [],
          runTime: '00:00:00',
          standbyTime: '00:00:00',
          warningTime: '00:00:00',
          shutdownTime: '00:00:00'
        };
      }

      // 根据设备ID生成固定的随机种子
      const seed = device.deviceId ? parseInt(device.deviceId) % 100 : 1;

      // 生成过去24小时的状态时间段数据
      const now = new Date();
      const statusDistribution = [];

      for (let i = 23; i >= 0; i--) {
        const startTime = new Date(now.getTime() - i * 60 * 60 * 1000);
        const duration = 60 * 60 * 1000; // 1小时
        const endTime = new Date(startTime.getTime() + duration);

        // 根据种子和时间生成状态，模拟真实生产场景
        let state;
        const hour = startTime.getHours();

        if (hour >= 8 && hour <= 12) {
          // 上午工作时间，倾向于运行
          const rand = (seed + i) % 10;
          state = rand < 7 ? '1' : (rand < 9 ? '2' : '3');
        } else if (hour >= 13 && hour <= 18) {
          // 下午工作时间，倾向于运行
          const rand = (seed + i) % 10;
          state = rand < 6 ? '1' : (rand < 8 ? '2' : (rand < 9 ? '3' : '0'));
        } else if (hour >= 19 && hour <= 22) {
          // 晚上，倾向于待机和关机
          const rand = (seed + i) % 10;
          state = rand < 3 ? '2' : (rand < 6 ? '1' : '0');
        } else {
          // 深夜和凌晨，主要是关机
          const rand = (seed + i) % 10;
          state = rand < 2 ? '2' : '0';
        }

        statusDistribution.push({
          startTime: startTime.toISOString(),
          endTime: endTime.toISOString(),
          duration: duration,
          state: state,
          yield: state === '1' ? Math.floor(Math.random() * 100 + 50) : 0 // 运行状态才有产量
        });
      }

      // 计算各状态的时长
      const totalHours = 24;
      let runHours = 0, standbyHours = 0, warningHours = 0, shutdownHours = 0;

      statusDistribution.forEach(item => {
        const hours = item.duration / (60 * 60 * 1000);
        switch(item.state) {
          case '1': runHours += hours; break;
          case '2': standbyHours += hours; break;
          case '3': warningHours += hours; break;
          case '0': shutdownHours += hours; break;
        }
      });

      // 转换为时间格式
      const formatTime = (hours) => {
        const h = Math.floor(hours);
        const m = Math.floor((hours - h) * 60);
        const s = Math.floor((hours - h - m / 60) * 3600);
        return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
      };

      // 计算百分比
      const runProp = Number(((runHours / totalHours) * 100).toFixed(2));
      const standbyProp = Number(((standbyHours / totalHours) * 100).toFixed(2));
      const warningProp = Number(((warningHours / totalHours) * 100).toFixed(2));
      const shutdownProp = Number(((shutdownHours / totalHours) * 100).toFixed(2));

      return {
        startRate: runProp.toString(),
        statusDistribution,
        runTime: formatTime(runHours),
        standbyTime: formatTime(standbyHours),
        warningTime: formatTime(warningHours),
        shutdownTime: formatTime(shutdownHours),
        runProp: runProp.toString(),
        standbyProp: standbyProp.toString(),
        warningProp: warningProp.toString(),
        shutdownProp: shutdownProp.toString()
      };
    },

    /**
     * 获取设备状态类名
     */
    getStatusClass(device) {
      if (!device || !device.status) return 'close';
      const statusConfig = this.deviceStatusConfig.find(config => config.value === device.status);
      return statusConfig ? statusConfig.class : 'close';
    },

    /**
     * 获取设备状态标签
     */
    getStatusLabel(device) {
      if (!device || !device.status) return '关机';
      const statusConfig = this.deviceStatusConfig.find(config => config.value === device.status);
      return statusConfig ? statusConfig.label : '关机';
    },

    /**
     * 获取状态对应的颜色
     */
    getStatusColor(className) {
      const statusConfig = this.deviceStatusConfig.find(config => config.class === className);
      return statusConfig ? statusConfig.color : '#777777';
    },

    /**
     * 获取仪表盘样式
     */
    getDashboardStyle(device) {
      if (!device) {
        return {
          '--dashboard-color': '#e6e6e6',
          background: 'conic-gradient(#e6e6e6 0% 0%, #e6e6e6 0% 100%)'
        };
      }

      const startRate = parseFloat(device.startRate || 0);
      let color = '#1ebe66'; // 默认绿色

      if (startRate < 60) {
        color = '#fd163c'; // 红色
      } else if (startRate < 80) {
        color = '#ffb900'; // 黄色
      }

      return {
        '--dashboard-color': color,
        background: `conic-gradient(${color} 0% ${startRate}%, #e6e6e6 ${startRate}% 100%)`
      };
    },

    /**
     * 搜索按钮操作
     */
    handleQuery() {
      this.queryParams.pageNo = 1;
      this.getList();
    },

    /**
     * 重置按钮操作
     */
    resetQuery() {
      if (this.$refs.queryForm) {
        this.$refs.queryForm.resetFields();
      }
      this.handleQuery();
    },

    /**
     * 处理树形数据
     */
    handleTree(data, id, parentId, children, rootId) {
      if (!data || !Array.isArray(data)) return [];

      id = id || 'id';
      parentId = parentId || 'parentId';
      children = children || 'children';

      // 计算根节点ID
      try {
        rootId = rootId || Math.min.apply(Math, data.map(item => item[parentId])) || 0;
      } catch {
        rootId = 0;
      }

      // 对源数据深度克隆
      const cloneData = JSON.parse(JSON.stringify(data));

      // 构建树形结构
      const treeData = cloneData.filter(father => {
        const branchArr = cloneData.filter(child => father[id] === child[parentId]);
        if (branchArr.length > 0) {
          father[children] = branchArr;
        }
        return father[parentId] === rootId;
      });

      return treeData.length > 0 ? treeData : cloneData;
    },

    /**
     * 树形选择器数据处理
     */
    normalizer(node) {
      return {
        id: node.id,
        label: node.name,
        children: node.children,
        isDisabled: node.deptType === 3
      };
    },

    /**
     * 获取模拟数据（用于开发测试）
     */
    getMockData() {
      return [
        {
          deviceId: '23',
          deviceNo: '6D6B成型机 SH001',
          deviceName: '6D6B成型机-001',
          status: '1',
          startRate: '53.46',
          deviceGroupId: '8',
          shutdownTime: '00:00:00',
          runTime: '08:06:16',
          standbyTime: '03:01:53',
          warningTime: '00:00:00',
          shutdownProp: '0.00',
          runProp: '53.46',
          standbyProp: '46.54',
          warningProp: '0.00'
        },
        {
          deviceId: '24',
          deviceNo: '6D6B成型机 SH002',
          deviceName: '6D6B成型机-002',
          status: '2',
          startRate: '64.89',
          deviceGroupId: '8',
          shutdownTime: '00:00:00',
          runTime: '09:50:16',
          standbyTime: '00:01:21',
          warningTime: '00:00:00',
          shutdownProp: '0.00',
          runProp: '64.89',
          standbyProp: '0.15',
          warningProp: '0.00'
        },
        {
          deviceId: '25',
          deviceNo: '6D6B成型机 SH003',
          deviceName: '6D6B成型机-003',
          status: '3',
          startRate: '78.22',
          deviceGroupId: '8',
          shutdownTime: '00:00:00',
          runTime: '11:52:45',
          standbyTime: '00:00:00',
          warningTime: '00:10:23',
          shutdownProp: '0.00',
          runProp: '78.22',
          standbyProp: '0.00',
          warningProp: '1.16'
        }
      ];
    }
  }
};
</script>

<style scoped>
.app-container {
  padding: 20px;
}

/* 弹框图表样式 */
.chart-section {
  margin-bottom: 30px;
}

.chart-title {
  margin: 0 0 15px 0;
  font-size: 16px;
  font-weight: 500;
  color: #333;
  border-bottom: 1px solid #e8e8e8;
  padding-bottom: 10px;
}

.chart-content {
  width: 100%;
  overflow: hidden;
}

.device-card-container {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  margin-top: 20px;
}

.device-card {
  cursor: pointer;
  transition: all 0.3s ease;
}

.device-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  transform: translateY(-2px);
}

.device-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.device-no {
  font-size: 16px;
  font-weight: bold;
}

.device-status {
  display: flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
}

.device-status i {
  margin-left: 5px;
  font-size: 10px;
}

.device-status.running {
  background-color: rgba(30, 190, 102, 0.1);
  color: #1ebe66;
}

.device-status.standby {
  background-color: rgba(255, 185, 0, 0.1);
  color: #ffb900;
}

.device-status.alarm {
  background-color: rgba(253, 22, 60, 0.1);
  color: #fd163c;
}

.device-status.close {
  background-color: rgba(119, 119, 119, 0.1);
  color: #777777;
}

.device-content {
  display: flex;
  align-items: center;
  gap: 20px;
}

.dashboard-container {
  flex-shrink: 0;
}

.dashboard {
  width: 80px;
  height: 80px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.dashboard-inner {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 12px;
}

.dashboard-percentage {
  font-size: 14px;
  font-weight: bold;
}

.status-list {
  flex: 1;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.status-item {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
}

.status-label {
  color: #606266;
}

.status-value {
  font-weight: 500;
}

.chart-section {
  margin: 20px 0;
}

.chart-title {
  font-size: 16px;
  font-weight: 500;
  margin-bottom: 15px;
}

.status-long-line-container {
  width: 100%;
}

.status-long-line {
  height: 20px;
  display: flex;
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 10px;
}

.status-line-segment {
  height: 100%;
  transition: width 0.3s ease;
}

.status-long-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  font-size: 12px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
}

.legend-color {
  width: 12px;
  height: 12px;
  border-radius: 2px;
}

.legend-color.running {
  background-color: #1ebe66;
}

.legend-color.standby {
  background-color: #ffb900;
}

.legend-color.alarm {
  background-color: #fd163c;
}

.legend-color.close {
  background-color: #777777;
}
</style>
